Message Handlers topic
The way a state responds to a message is defined by the MessageHandler function for the state. A
message handler is provided a MessageContext describing the message, and must return a
MessageResult describing how the state responds to the message.
typedef MessageHandler = FutureOr<MessageResult> Function(MessageContext ctx);
Methods on the provided MessageContext can be used to create the desired message result. For
example, goTo(), unhandled(), or stay()
Because a message handler returns a FutureOr, the handler implementation may be asynchronous if
desired.
A message handler is provided with the onMessage callback when creating the state:
class GoToLogin { }
enum Messages { goToRegister }
State(
States.unauthenticated,
onMessage: (MessageContext ctx) {
return switch(ctx.message) {
// When this state receives a message of type GoToLogin, go to the login
// state
GoToLogin() => ctx.goTo(States.login),
// When this state receives a goToRegister message value, go to the
// registration state
Messages.goToRegister => mhb.goTo(States.registration),
// Otherwise, the message is unhandled. An ancestor state can handle it instead.
_ => ctx.unhandled()
};
},
);
Reading and writing state data
A data state can access its associated state data. Additionally, any state can access the state data of an ancestor data state.
State data is stored in a DataValue<D> instance. A DataValue provides access to the current
state data value with the value property. The DataValue for a data state can be requested using
the MessageContext.data and TransitionContext.data methods.
A DataValue is also a Stream, and therefore can be used to observe changes to the state data
over time. This is not typically used in a message handler, but DataValues are also accessible
from a TreeStateMachine, and the change notifications can prove useful at the application level.
The DataValue.update method can be use to update the current value, which will cause the
associated Stream to emit a new value.
State(
States.credentialsRegistration,
onMessage: (ctx) {
if (ctx.message case SubmitCredentials(email: var email, password: var password)) {
// Update the RegisterData state data owned by an ancestor Register state.
ctx.data(States.register).update((RegisterData data) => data
..email = email
..password = password);
return ctx.goTo(States.demographicsRegistration);
}
return ctx.unhandled();
},
);
Classes
-
DataState<
D> State Trees Transition Handlers -
A data state with associated state data of type
D. -
DataValue<
T> -
Provides access to a data value of type
Tassociated with a data state. - MessageContext
- Provides information to a state about the message that is being processed.
- State State Trees Transition Handlers
- A state in a state tree.
Typedefs
-
MessageHandler
= FutureOr<
MessageResult> Function(MessageContext ctx) - Type of functions that process messages sent to a state machine.